/*
 * Albareth - an action roleplaying game.
 * Copyright (C) 2008 Jens Anuth
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *   02110-1301, USA.
 * 
 * $Id: SlickResources.java 48 2008-05-17 02:04:48Z jens464 $
*/
package albareth.frontend.slick;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.lwjgl.input.Cursor;
import org.newdawn.slick.AngelCodeFont;
import org.newdawn.slick.BigImage;
import org.newdawn.slick.Font;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.loading.LoadingList;
import org.newdawn.slick.particles.ConfigurableEmitter;
import org.newdawn.slick.particles.ConfigurableEmitterFactory;
import org.newdawn.slick.particles.ParticleIO;
import org.newdawn.slick.particles.ParticleSystem;

import frosch.slick.particle.FastDuplicatableEmitter;

import albareth.frontend.Resources;
import albareth.frontend.Tile;
import albareth.frontend.TileCollection;
import albareth.frontend.Tileset;
import albareth.frontend.slick.ui.UIToolkit;


public class SlickResources extends Resources
{

    //public static ParticleSystem EMPTY_PARTICLE_SYSTEM;
    
    public static Font DEFAULT_FONT = null;
    public static Font SMALL_FONT = null;
    public static Cursor DEFAULT_MOUSE_CURSOR = null; //lazily loaded
    
    public static Image IN_GAME_BG = null;
    public static Image TITLE_BG = null;
    public static Image EQUIP_BG = null;
    public static Image CONTAINER_BG = null;
    public static Image INVENTORY_TITLE = null;
    public static Image DUNGEON_WIN_BORDER = null;
    public static Image QUICKBAR = null;
    public static Image HP_BAR_EMPTY = null;
    public static Image HP_BAR_FULL = null;
    public static Image CASTING_BAR_EMPTY = null;
    public static Image CASTING_BAR_FULL = null;
    public static Image MOUSE_CURSORS = null;
    public static Image IMG_DARKEN = null;
    public static Image SCROLL = null;
    public static Image AVATAR_CHOOSE_BG = null;
    public static Image BUTTON = null;
    public static Image BUTTON_PRESSED = null;
    public static Image BUTTON_HOVER = null;
    public static Image BUTTON_INV_NORMAL = null;
    public static Image BUTTON_INV_PRESSED = null;
    public static Image BUTTON_EQ_NORMAL = null;
    public static Image BUTTON_EQ_PRESSED = null;
    public static Image BUTTON_MAP_NORMAL = null;
    public static Image BUTTON_MAP_PRESSED = null;
    public static Image RULER = null;
    public static Image CREATE_YOUR_CHAR = null;
    public static Image MENU_ITEM_BG = null;
    public static Image MENU_ITEM_SELECTED = null;
    public static Image BUFF_BENEFICAL = null;
    public static Image BUFF_HARMFUL = null;
    public static Image MENU_ITEM_DISABLED = null;
    
    public static SpriteSheet SHEET_MOUSE_CURSORS = null;

    public static Cursor CURSOR_DEFAULT = null;
    public static Cursor CURSOR_FIST = null;
    public static Cursor CURSOR_FORBIDDEN = null;
    public static Cursor CURSOR_SWORD = null;
    public static Cursor CURSOR_NOSWORD = null;
    public static Cursor CURSOR_N = null;
    public static Cursor CURSOR_E = null;
    public static Cursor CURSOR_S = null;
    public static Cursor CURSOR_W = null;
    public static Cursor CURSOR_NE = null;
    public static Cursor CURSOR_NW = null;
    public static Cursor CURSOR_SW = null;
    public static Cursor CURSOR_SE = null;

    private static Map _tilesets = new HashMap();
    private static Map _particleSystems = new HashMap();
    private static Map _sounds = new HashMap();

    

    public static void loadAll() throws SlickException
    {
        //STATIC IMAGES:
        MOUSE_CURSORS = new Image("res/img/cursors_32x32.png");
        CASTING_BAR_EMPTY = new Image("res/img/casting_bar_empty.png");
        CASTING_BAR_FULL = new Image("res/img/casting_bar_full.png");
        SlickResources.loadSheets();
        SlickResources.loadMouseCursors();
        SlickResources.loadFonts();

        //DEFERRED IMAGES:
        LoadingList.setDeferredLoading(true);
        
        TITLE_BG = new BigImage("res/img/title_screen.png");
        IN_GAME_BG = new BigImage("res/img/in_game_bg.png");
        EQUIP_BG = new BigImage("res/img/equip_bg.png");
        CONTAINER_BG = new Image("res/img/container_bg.png");
        DUNGEON_WIN_BORDER = new Image("res/img/dungeon_win_border.png");
        QUICKBAR = new Image("res/img/quickbar.png");
        HP_BAR_EMPTY = new Image("res/img/hp_bar_empty.png");
        HP_BAR_FULL = new Image("res/img/hp_bar_full.png");
        IMG_DARKEN = new BigImage("res/img/darken.png");
        SCROLL = new BigImage("res/img/scroll_bg.png");
        AVATAR_CHOOSE_BG = new Image("res/img/avatar_choose_menu.png");
        BUTTON = new Image("res/img/button.png");
        BUTTON_PRESSED = new Image("res/img/button_pressed.png");
        BUTTON_HOVER = new Image("res/img/button_hover.png");
        BUTTON_INV_NORMAL = new Image("res/img/inv_btn_normal.png");
        BUTTON_INV_PRESSED = new Image("res/img/inv_btn_pressed.png");
        BUTTON_EQ_NORMAL = new Image("res/img/eq_btn_normal.png");
        BUTTON_EQ_PRESSED = new Image("res/img/eq_btn_pressed.png");
        BUTTON_MAP_NORMAL = new Image("res/img/map_btn_normal.png");
        BUTTON_MAP_PRESSED = new Image("res/img/map_btn_pressed.png");

        RULER = new Image("res/img/ruler.png");
        CREATE_YOUR_CHAR = new Image("res/img/create_your_char.png");
        MENU_ITEM_SELECTED = new Image("res/img/menu_item_selected.png");
        MENU_ITEM_DISABLED = new Image("res/img/menu_item_disabled.png");
        MENU_ITEM_BG = new Image("res/img/menu_item_bg.png");
        INVENTORY_TITLE = new Image("res/img/inventory_title.png");
        BUFF_BENEFICAL = new Image("res/img/buff_benefical.png");
        BUFF_HARMFUL = new Image("res/img/buff_harmful.png");
        
        SlickResources.loadParticles();
        SlickResources.loadSounds();        

    }
    
    public static void loadFonts() throws SlickException
    {
        DEFAULT_FONT = new AngelCodeFont("res/goldbox.fnt", "res/goldbox.png");
        SMALL_FONT = new AngelCodeFont("res/smallfont.fnt", "res/smallfont_00.png");
    }

    public static void loadMouseCursors() throws SlickException
    {
        CURSOR_DEFAULT = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(8, 0), 16, 16
        );
        CURSOR_N = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(0, 0), 16, 16
        );
        CURSOR_E = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(1, 0), 16, 16
        );
        CURSOR_S = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(2, 0), 16, 16
        );
        CURSOR_W = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(3, 0), 16, 16
        );
        CURSOR_NE = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(4, 0), 16, 16
        );
        CURSOR_NW = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(5, 0), 16, 16
        );
        CURSOR_SW =  UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(6, 0), 16, 16
        );
        CURSOR_SE = UIToolkit.createMouseCursorFromImage(
                SlickResources.SHEET_MOUSE_CURSORS.getSprite(7, 0), 16, 16
        );
        CURSOR_FIST = UIToolkit.createMouseCursorFromImage(
                getTileImage(TileCollection.ICON_FIST), 16, 16, 2
        );
        CURSOR_FORBIDDEN = UIToolkit.createMouseCursorFromImage(
                getTileImage(TileCollection.ICON_FORBIDDEN), 16, 16, 2
        );
        CURSOR_SWORD = UIToolkit.createMouseCursorFromImage(
                getTileImage(TileCollection.ICON_SWORD), 16, 16, 2
        );
        CURSOR_NOSWORD = UIToolkit.createMouseCursorFromImage(
                getTileImage(TileCollection.ICON_NOSWORD), 16, 16, 2
        );


    }

    public static void loadSounds() throws SlickException
    {
        _sounds.put(Resources.SOUND_TITLE_TUNE, new Sound("res/snd/title_tune.ogg"));
        _sounds.put(Resources.SOUND_FIREBALL, new Sound("res/snd/fireball_fly.ogg"));
        _sounds.put(Resources.SOUND_MAGIC_MISSILE, new Sound("res/snd/magic_missile_fly.ogg"));
        _sounds.put(Resources.SOUND_EATING, new Sound("res/snd/eating.ogg"));
        _sounds.put(Resources.SOUND_DRINKING, new Sound("res/snd/drinking.ogg"));
        _sounds.put(Resources.SOUND_FROSTNOVA, new Sound("res/snd/glass_break_snd.ogg"));
        _sounds.put(Resources.SOUND_MELEE_HIT, new Sound("res/snd/fight_hit.ogg"));
        _sounds.put(Resources.SOUND_MELEE_CRITICAL_HIT, new Sound("res/snd/fight_critical_hit.ogg"));
        _sounds.put(Resources.SOUND_MELEE_MISS, new Sound("res/snd/whoosh_miss.ogg"));
        _sounds.put(Resources.SOUND_EXPLO_LARGE, new Sound("res/snd/large_explosion.ogg"));
        _sounds.put(Resources.SOUND_EXPLO_MAGIC, new Sound("res/snd/magic_hit.ogg"));
        _sounds.put(Resources.SOUND_OUCH, new Sound("res/snd/player_get_crit.ogg"));
        _sounds.put(Resources.SOUND_OPEN_CHEST, new Sound("res/snd/open_chest.ogg"));
        _sounds.put(Resources.SOUND_STUMBLING, new Sound("res/snd/stumbling.ogg"));
        _sounds.put(Resources.SOUND_NPC_STUMBLING, new Sound("res/snd/npc_stumbling.ogg"));
        _sounds.put(Resources.SOUND_CONTAINER_BREAK, new Sound("res/snd/break_container.ogg"));
        _sounds.put(Resources.SOUND_ROLL_IN, new Sound("res/snd/scroll_roll_in.ogg"));
        _sounds.put(Resources.SOUND_BUTTON_POP, new Sound("res/snd/button_pop.ogg"));
        _sounds.put(Resources.SOUND_HURL, new Sound("res/snd/hurl.ogg"));
        _sounds.put(Resources.SOUND_THROW, new Sound("res/snd/throw.ogg"));
        _sounds.put(Resources.SOUND_RANGED_HIT, new Sound("res/snd/projectile_hit.ogg"));
        _sounds.put(Resources.SOUND_SLIME, new Sound("res/snd/slime_hit.ogg"));
        _sounds.put(Resources.SOUND_SPELL_HEAL, new Sound("res/snd/spell_heal.ogg"));
        _sounds.put(Resources.SOUND_BOSS_APPEAR, new Sound("res/snd/boss_appear.ogg"));
        _sounds.put(Resources.SOUND_LEVEL_UP, new Sound("res/snd/level_up.ogg"));
        _sounds.put(Resources.SOUND_FUSE_LIGHTER, new Sound("res/snd/fuse_lighter.ogg"));
        _sounds.put(Resources.SOUND_PICKUP_GOLD, new Sound("res/snd/pickup_gold.ogg"));
        //_sounds.put(Resources.SOUND_ROLL_BACK, new Sound("res/snd/scroll_roll_back.ogg"));
    }

    public static void loadParticles() throws SlickException
    {
        try
        {
            ConfigurableEmitterFactory factory =
                new FastDuplicatableEmitter("factory");
            
            //EMPTY_PARTICLE_SYSTEM =
            //    ParticleIO.loadConfiguredSystem("res/particle/emptysystem.xml", factory);

            /*
            //fireball particles
            ConfigurableEmitter fireballEmitter =
                ParticleIO.loadEmitter("res/particle/fireball_emitter.xml", factory);
            ParticleSystem fireballSystem = EMPTY_PARTICLE_SYSTEM.duplicate();
            fireballSystem.addEmitter(fireballEmitter);
            _particleSystems.put(Resources.EFFECT_FIREBALL, fireballSystem);
            */
            
            //fireball:
            _particleSystems.put(
                    Resources.EFFECT_FIREBALL,
                    ParticleIO.loadConfiguredSystem("res/particle/fireball_system.xml", factory)
            );


            //frostnova:
            _particleSystems.put(
                    Resources.EFFECT_FROSTNOVA,
                    ParticleIO.loadConfiguredSystem("res/particle/frostnova_system.xml", factory)
            );
            //magic missile:
            _particleSystems.put(
                    Resources.EFFECT_MAGICMISSILE,
                    ParticleIO.loadConfiguredSystem("res/particle/magicmissile_system.xml", factory)
            );

            //magic explosion:
            _particleSystems.put(
                    Resources.EFFECT_MAGICEXPLOSION,
                    ParticleIO.loadConfiguredSystem("res/particle/magicexplosion_system.xml", factory)
            );

            //explosion:
            _particleSystems.put(
                    Resources.EFFECT_EXPLOSION,
                    ParticleIO.loadConfiguredSystem("res/particle/explosion_system.xml", factory)
            );

            //dust:
            _particleSystems.put(
                    Resources.EFFECT_DUST,
                    ParticleIO.loadConfiguredSystem("res/particle/dust_system.xml", factory)
            );

            //debris:
            _particleSystems.put(
                    Resources.EFFECT_DEBRIS,
                    ParticleIO.loadConfiguredSystem("res/particle/debris_system.xml", factory)
            );
            
            //poison:
            _particleSystems.put(
                    Resources.EFFECT_POISON_HIT,
                    ParticleIO.loadConfiguredSystem("res/particle/poison_hit_system.xml", factory)
            );
            _particleSystems.put(
                    Resources.EFFECT_POISON_SHOOT,
                    ParticleIO.loadConfiguredSystem("res/particle/poison_shoot_system.xml", factory)
            );
            
            //heal
            _particleSystems.put(
                    Resources.EFFECT_HEAL_SPARKLE,
                    ParticleIO.loadConfiguredSystem("res/particle/heal_system.xml", factory)
            );
            
            //Boss aura:
            _particleSystems.put(
                    Resources.EFFECT_BOSS,
                    ParticleIO.loadConfiguredSystem("res/particle/boss_system.xml", factory)
            );

            //level up:
            _particleSystems.put(
                    Resources.EFFECT_LEVEL_UP,
                    ParticleIO.loadConfiguredSystem("res/particle/level_up_system.xml", factory)
            );

            //fuse:
            _particleSystems.put(
                    Resources.EFFECT_FUSE,
                    ParticleIO.loadConfiguredSystem("res/particle/fuse_system.xml", factory)
            );

            
            
        } catch (IOException e) {
            throw new SlickException("Error loading particle systems", e); 
        }

    }

    public static void loadSheets()
    {
        SHEET_MOUSE_CURSORS = new SpriteSheet(MOUSE_CURSORS, 32, 32);
    }

    public static ParticleSystem getParticleSystem(String stringId)
    {
        return (ParticleSystem)_particleSystems.get(stringId);
    }

    public static Sound getSound(String stringId)
    {
        return (Sound)_sounds.get(stringId);
    }
    
    public static Image getTileImage(Tile tile) throws SlickException
    {
        Tileset tileset = tile.getTileset();
        SpriteSheet sheet = (SpriteSheet)_tilesets.get(tileset.getTilesetUri());
        if (sheet == null)
        {
            sheet = new SpriteSheet(
                    tileset.getTilesetUri(),
                    tileset.getTileWidth(),
                    tileset.getTileHeight()
            );
            _tilesets.put(tileset.getTilesetUri(), sheet);
        }
        return sheet.getSprite(tile.getX(), tile.getY());
    }


}
